﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WPFCode
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            InitCanvas();
            NewModel();
        }
        private void InitCanvas()
        {
            Canvas_Width = (int)MyCanvas.Width / M_Width;
            Canvas_Height = (int)MyCanvas.Height / M_Width;
        }

        private static int Canvas_Width = 0;
        private static int Canvas_Height = 0;
        private static int M_Width = 20;
        private static int M_Speed = 1000;


        private MoveModel CurrentModel = null;
        private void DrawDemo()
        {
            Random rd = new Random();
            //var randomColor = ColorCollection[rd.Next(0, ColorCollection.Count - 1)];
            var randomColor = Brushes.Yellow;
            // 创建一个矩形对象
            Rectangle rectangle = new Rectangle();
            rectangle.Width = M_Width;
            rectangle.Height = M_Width;
            // 设置矩形的颜色和边框
            rectangle.Fill = randomColor;
            //边框
            rectangle.Stroke = Brushes.Black;
            rectangle.StrokeThickness = 1;
            // 设置矩形的位置
            Canvas.SetLeft(rectangle, 0);
            Canvas.SetTop(rectangle, 0);
            // 在Canvas上绘制矩形
            MyCanvas.Children.Add(rectangle);

        }

        private List<MoveModelBase> DrawItemBaseList = new List<MoveModelBase>()
        {
            new MoveModelBase(Brushes.Yellow, new List<MoveModelBase.SubItem> { new MoveModelBase.SubItem(0, 0), new MoveModelBase.SubItem(0, 1), new MoveModelBase.SubItem(0, 2), new MoveModelBase.SubItem(1, 2) }),//L
            new MoveModelBase(Brushes.Yellow, new List<MoveModelBase.SubItem> { new MoveModelBase.SubItem(0, 2), new MoveModelBase.SubItem(1, 0), new MoveModelBase.SubItem(1, 1), new MoveModelBase.SubItem(1, 2) }),//反L
            new MoveModelBase(Brushes.Red, new List<MoveModelBase.SubItem> { new MoveModelBase.SubItem(0, 0), new MoveModelBase.SubItem(0, 1), new MoveModelBase.SubItem(1, 0), new MoveModelBase.SubItem(1, 1) },0),//田
            new MoveModelBase(Brushes.Blue, new List<MoveModelBase.SubItem> { new MoveModelBase.SubItem(0, 1), new MoveModelBase.SubItem(1, 0), new MoveModelBase.SubItem(1, 1), new MoveModelBase.SubItem(1, 2) }),//土
            new MoveModelBase(Brushes.Green, new List<MoveModelBase.SubItem> { new MoveModelBase.SubItem(0, 0), new MoveModelBase.SubItem(1, 0), new MoveModelBase.SubItem(2, 0), new MoveModelBase.SubItem(3, 0) },2),//竖
            new MoveModelBase(Brushes.Pink, new List<MoveModelBase.SubItem> { new MoveModelBase.SubItem(0, 0), new MoveModelBase.SubItem(0, 1), new MoveModelBase.SubItem(1, 1), new MoveModelBase.SubItem(1, 2) },2),//Z
            new MoveModelBase(Brushes.Pink, new List<MoveModelBase.SubItem> { new MoveModelBase.SubItem(0, 1), new MoveModelBase.SubItem(0, 2), new MoveModelBase.SubItem(1, 0), new MoveModelBase.SubItem(1, 1) },2),//反Z
        };
        private void NewModel()
        {
            Random dm = new Random();
            var i = dm.Next(0, 7);
            var randomModel = DrawItemBaseList[i];
            List<MoveModel.CanvasModel> items = new List<MoveModel.CanvasModel>();
            randomModel.List.ForEach(_ =>
            {
                items.Add(new MoveModel.CanvasModel { Item = DrawFangkuai(randomModel.Color, _.X, _.Y), X = _.X, Y = _.Y });
            });
            CurrentModel = new MoveModel(items, randomModel.Color, randomModel.RotateTime);
        }

        private Rectangle DrawFangkuai(SolidColorBrush color, int x, int y)
        {
            var x_val = x * M_Width;
            var y_val = y * M_Width;
            // 创建一个矩形对象
            Rectangle rectangle = new Rectangle();
            rectangle.Width = M_Width;
            rectangle.Height = M_Width;
            // 设置矩形的颜色和边框
            rectangle.Fill = color;
            //边框
            rectangle.Stroke = Brushes.Black;
            rectangle.StrokeThickness = 1;
            // 设置矩形的位置
            Canvas.SetLeft(rectangle, x_val);
            Canvas.SetTop(rectangle, y_val);
            // 在Canvas上绘制矩形
            MyCanvas.Children.Add(rectangle);
            return rectangle;
        }

        public class MoveModel
        {
            public MoveModel(List<CanvasModel> datas, SolidColorBrush color, int rotateTime = 4)
            {
                ItemBlock = datas;
                RotateTime = rotateTime;
                Color = color;
                RefreshPosition();
                RefreshRotatePoint();
            }
            private List<CanvasModel> ItemBlock = new List<CanvasModel>();
            /// <summary>
            /// 旋转次数
            /// </summary>
            public int RotateTime { get; set; }
            /// <summary>
            /// 颜色
            /// </summary>
            public SolidColorBrush Color { get; set; }
            public void RotateL()
            {

            }
            public void RotateR()
            {
                if (RotateTime == 0)
                    return;
                var rotateX = RatatePoint_X;
                var rotateY = RatatePoint_Y;
                if (RotateTime == 4)
                {
         
                    foreach (var item in ItemBlock)
                    {
                        var x = item.X - rotateX;
                        var y = item.Y - rotateY;

                        item.X = y + rotateX;
                        item.Y = x * (-1) + rotateY;
                    }
                }
                if (RotateTime == 2)
                {
                    var x1 = ((MinX + MaxX) % 2) > 0 ? (MinX + MaxX + 1) / 2 : (MinX + MaxX) / 2;
                    var y1 = ((MinY + MaxY) % 2) > 0 ? (MinY + MaxY + 1) / 2 : (MinY + MaxY) / 2;
                    if (x1 != RatatePoint_X || y1 != RatatePoint_Y)
                    {
                        foreach (var item in ItemBlock)
                        {
                            var x = item.X - rotateX;
                            var y = item.Y - rotateY;

                            item.X = y * (-1) + rotateX;
                            item.Y = x + rotateY;
                        }
                    }
                    else
                    {
                        foreach (var item in ItemBlock)
                        {
                            var x = item.X - rotateX;
                            var y = item.Y - rotateY;

                            item.X = y + rotateX;
                            item.Y = x * (-1) + rotateY;
                        }
                    }

                }
                RefreshPosition();
                //RefreshRotatePoint();

                //var newRotateX = RatatePoint_X;
                //var newRotateY = RatatePoint_Y;
                //if (newRotateX != rotateX || newRotateY != rotateY)
                //{
                //    if (rotateX > newRotateX)
                //        ToRight(rotateX - newRotateX);
                //    if (rotateX < newRotateX)
                //        ToLeft(newRotateX - rotateX);
                //    if (rotateY > newRotateY)
                //        ToDown(rotateY - newRotateY);
                //    if (rotateY < newRotateY)
                //        ToUp(newRotateY - rotateY);
                //    RefreshPosition();
                //    //RefreshRotatePoint();
                //}
            }
            void UpdateMaxMinVal()
            {
                MinX = MaxX = ItemBlock.First().X;
                MinY = MaxY = ItemBlock.First().Y;
                foreach (var item in ItemBlock)
                {
                    var x = item.X;
                    var y = item.Y;
                    if (MaxX < x)
                        MaxX = x;
                    if (MinX > x)
                        MinX = x;
                    if (MaxY < y)
                        MaxY = y;
                    if (MinY > y)
                        MinY = y;
                }
            }
            public int MaxX { get; private set; }
            public int MinX { get; private set; }
            public int MaxY { get; private set; }
            public int MinY { get; private set; }
            private void RefreshRotatePoint()
            {
                RatatePoint_X = ((MinX + MaxX) % 2) > 0 ? (MinX + MaxX + 1) / 2 : (MinX + MaxX) / 2;
                RatatePoint_Y = ((MinY + MaxY) % 2) > 0 ? (MinY + MaxY + 1) / 2 : (MinY + MaxY) / 2;
            }

            private int RatatePoint_X { get; set; }
            private int RatatePoint_Y { get; set; }
            public void MoveTo(Key key)
            {
                switch (key)
                {
                    case Key.Left:
                        ToLeft();
                        break;
                    case Key.Right:
                        ToRight();
                        break;
                    case Key.Up:
                        ToUp();
                        break;
                    case Key.Down:
                        ToDown();
                        break;
                    case Key.Space:
                        break;
                }
                RefreshPosition();
                RefreshRotatePoint();
            }

            public void RefreshPosition()
            {
                foreach (var item in ItemBlock)
                {
                    var block = item.Item;
                    block.Fill = Color;
                    Canvas.SetLeft(block, item.X * M_Width);
                    Canvas.SetTop(block, item.Y * M_Width);
                }
                UpdateMaxMinVal();

            }

            private void ToLeft(int step = 1)
            {
                if ((MinX - step) < 0)
                    return;
                foreach (var item in ItemBlock)
                {
                    item.X -= step;
                }
            }
            private void ToRight(int step = 1)
            {
                if ((MaxX + step) >= Canvas_Width)
                    return;
                foreach (var item in ItemBlock)
                {
                    item.X += step;
                }
            }
            private void ToUp(int step = 1)
            {
                if ((MinY - step) < 0)
                    return;
                foreach (var item in ItemBlock)
                {
                    item.Y -= step;
                }
            }
            private void ToDown(int step = 1)
            {
                if ((MaxY + step) >= Canvas_Height)
                    return;
                foreach (var item in ItemBlock)
                {
                    item.Y += step;
                }
            }
            public class CanvasModel
            {
                public Rectangle Item { get; set; }
                public int X { get; set; }
                public int Y { get; set; }
            }
        }
        public class MoveModelBase
        {
            public MoveModelBase(SolidColorBrush color, List<SubItem> list, int rotateTime = 4)
            {
                Color = color;
                List = list;
                RotateTime = rotateTime;
            }
            public SolidColorBrush Color { get; set; }
            /// <summary>
            /// 旋转次数
            /// </summary>
            public int RotateTime { get; set; }
            public List<SubItem> List { get; set; }
            public class SubItem
            {
                public SubItem(int x, int y)
                {
                    X = x;
                    Y = y;
                }
                public int X { get; set; }
                public int Y { get; set; }
            }
        }

        private void Move(Key key)
        {
            if (key != Key.Space)
                CurrentModel.MoveTo(key);
            else
                NewModel();
        }

        private void Button_Change(object sender, KeyEventArgs e)
        {
            string text = TextInfo.Text;
            text += e.Key.ToString();
            if (text.Length > 100)
                text = text.Substring(text.Length - 100, 100);
            TextInfo.Text = text;
            var key = e.Key;
            if (key == Key.Enter)
                NewModel();
            else if (key == Key.Space)
                CurrentModel.RotateR();
            else CurrentModel.MoveTo(key);
        }

    }
}
